package user;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import fj.F;
import global.Global;

import server.db.DatabaseFunctor;
import server.db.StmtHelper;
import util.Validation;

import ajaxmethods.SessionMethod;

public class CreateAcct extends SessionMethod {

	public static String KAPTCHA_ERROR="The characters entered do not match";
	private List<String> requiredFields = Arrays.asList("firstname","lastname","email","password","password2","kaptcha");
	private Map<String,String> fieldsMap = new HashMap();
	private String kaptchakey;
	private JSONArray errors = new JSONArray();
	private F<Map<String, List<String>>, DatabaseFunctor<Integer>> insertUser = new F<Map<String, List<String>>, DatabaseFunctor<Integer>>()
	{

		@Override
		public DatabaseFunctor<Integer> f(Map<String, List<String>> canInsert) {
			
			if(canInsert.get("email").size()<1)
			{
				return StmtHelper.db("insert into user (firstname,lastname,email,password,idusertype) values (")
					.addVariable(fieldsMap.get("firstname")).addSql(",")
					.addVariable(fieldsMap.get("lastname")).addSql(",")
					.addVariable(fieldsMap.get("email")).addSql(",")
					.addVariable(fieldsMap.get("password")).addSql(",")
					.addSql("(select idusertype from usertype where code='CONSUMER'))").executeUpdate();
			}
			addError(canInsert.get("email").get(0)+" is not available","email");
			return null;
		}
		
	};
	
	@Override
	public void perform(HttpServletRequest request, HttpServletResponse response) {
		super.perform(request, response);
		kaptchakey = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
		String fields = request.getParameter("fields");

		for(String field : fields.split(","))
		{
			String[] fvPair = field.split(":");
			if(fvPair.length>1)
			{
				fieldsMap.put(fvPair[0],fvPair[1]);
			}
		}
		validate();
		if(errors.length()<1)
		{
			try {
				StmtHelper.db("select email from user where email=")
					.addVariable(fieldsMap.get("email")).collectStrings.provideTo(insertUser).unsafeUpdate();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		JSONObject redirectObj = new JSONObject();
		Global global = new Global(request);
		if(errors.length() < 1)
		{
			//TODO: email user
			
			//build success object
			
			global.login(fieldsMap.get("email"),fieldsMap.get("password"),true);
			
			if(fieldsMap.containsKey("redirect") && fieldsMap.get("redirect")!=null && fieldsMap.get("redirect").length()>0)
			{
				try {
					redirectObj.put("redirect", fieldsMap.get("redirect"));
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			
		}
			try {
				JSONObject returnobj = new JSONObject();
				if(global.getUser()!=null)
					returnobj = global.getUser().toJson();
				returnobj.put("createacct",redirectObj);
				if(errors.length()>0)
					returnobj.put("errors", errors);
				returnobj.write(response.getWriter());
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	
	}

	private void validate() {
		//check requiredness
		for(String fieldName : requiredFields)
		{
			if(fieldsMap.get(fieldName)==null ||"".equals(fieldsMap.get(fieldName)))
				addError("required",fieldName);
		}
		if(errors.length()<1)
		{
			//validate email address
			if(!Validation.isValidEmailAddress(fieldsMap.get("email")))
			{
				addError("Not a valid email address","email");
			}
			//check for password correct-ness
			if(!fieldsMap.get("password").equals(fieldsMap.get("password2"))) {
				addError("Passwords do not match","password");
				addError("Passwords do not match","password2");
			}
			if(!kaptchakey.equals(fieldsMap.get("kaptcha")))
				addError(KAPTCHA_ERROR,"kaptcha");
		}
	}

	private void addError(String errortype, String fieldName) {
		JSONObject error;
		try {
			error = new JSONObject().put("error", errortype).put("fieldname",fieldName);
			errors.put(error);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

}
